package com.ruoyi.system.utils;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.lang.reflect.MethodHandleUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.system.annotation.ExcelTransition;
import com.ruoyi.system.domain.pojo.YQExcelUpInfo;
import com.ruoyi.system.domain.simport.TxwjYqTianBao;

import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 疫情信息构造工具
 * 该工具用于读取 类上的注解，拼备注，并可设置 excel 单元格位置，相同的数字自动合并，逗号分隔
 */
public class YQInfoBuildUtils {

    /**
     * 读取腾讯问卷导出的 excel 转换为 疫情填报报表的excel
     * @param txwjYqTianBao
     * @return
     */
    public static YQExcelUpInfo readExcelInfo(TxwjYqTianBao txwjYqTianBao, Map<Integer, String> titleMap) {
        TxwjYqTianBao txwjYqTianBao1 = parseInfoAndRebuild(txwjYqTianBao, titleMap);

        YQExcelUpInfo yqExcelUpInfo = new YQExcelUpInfo();

        // 将 txwjYqTianBao1 转换为  YQExcelUpInfo
        Field[] fields = ReflectUtil.getFields(TxwjYqTianBao.class);
        for (Field field : fields) {
            // 如果有的话
            if(field.isAnnotationPresent(ExcelTransition.class)) {
                String fieldValue = getFieldValue(field.getName(), txwjYqTianBao1, TxwjYqTianBao.class);
                ExcelTransition annotation = field.getAnnotation(ExcelTransition.class);
                String lastFieldValue = getFieldValue(annotation.transField(), yqExcelUpInfo, YQExcelUpInfo.class);
                String newValue = fieldValue;
                if(StrUtil.isNotBlank(lastFieldValue)) {
                    newValue = lastFieldValue + ","  + fieldValue;
                }
                setFieldValue(annotation.transField(), newValue, yqExcelUpInfo, YQExcelUpInfo.class);
            }
        }

        return yqExcelUpInfo;
    }

    /**
     * 解析注解信息 重新按注解规则 返回新的列数据
     * @param txwjYqTianBao
     */
    public static TxwjYqTianBao parseInfoAndRebuild(TxwjYqTianBao txwjYqTianBao, Map<Integer, String> titleMap) {
        // 克隆一下 然后在克隆的对象上改
        TxwjYqTianBao nTianBao = txwjYqTianBao.clone();

        Field[] fields = ReflectUtil.getFields(TxwjYqTianBao.class);
        for (Field field : fields) {
            // 如果有的话
            if(field.isAnnotationPresent(ExcelTransition.class)) {
                // 名字一会执行 set 方法
                String fieldName = field.getName();
                // 获取注解
                // 根据注解上的 参数 去 map 里 寻找对应值，然后 get 出来 然后 set 回去。
                ExcelTransition annotation = field.getAnnotation(ExcelTransition.class);
                String titleContains = annotation.readTitleContains();
                String value = findTitleValueFromMap(titleContains, titleMap, txwjYqTianBao);

                setFieldValue(fieldName, value, nTianBao, TxwjYqTianBao.class);
            }
        }

        return nTianBao;
    }

    private static String findTitleValueFromMap(String title, Map<Integer, String> titleMap, TxwjYqTianBao txwjYqTianBao) {
        for(Map.Entry<Integer, String> entry : titleMap.entrySet()) {
            if(entry == null) {
                continue;
            }
            String value = Optional.ofNullable(entry.getValue()).orElse("");
            if(value.contains(title)) {
                String fieldName =  "column" + entry.getKey();
                return getFieldValue(fieldName, txwjYqTianBao, TxwjYqTianBao.class);
            }
        }
        return "";
    }

    private static void setFieldValue(String fieldName, String value, Object o, Class<?> clazz) {
        // set 回去
        String setFieldMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        Method method = ReflectUtil.getMethodByName(clazz, setFieldMethodName);
        try {
            method.invoke(o, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String getFieldValue(String fieldName, Object o, Class<?> clazz) {
        String getfieldMethodName =  "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        Method method = ReflectUtil.getMethodByName(clazz, getfieldMethodName);
        if(method == null) {
            System.out.println(clazz.getName() + getfieldMethodName + "为空");
        }
        String v = "";
        try {
            Object r = method.invoke(o);
            if(r == null) {
                return "";
            }
            v = (String) Optional.of(r).orElse("");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return v;
    }

    public static void main(String[] args) {
        parseInfoAndRebuild(new TxwjYqTianBao(), new HashMap<>());
    }

}
